//using System;
//using System.Reflection;
//using System.IO;
//using System.Collections;
//using System.Xml.Serialization;
//using DCRF.Common.Kernel.Helper;
//using DCRF.Common.Kernel.Core;
//using DCRF.Common.Core;
//using DCRF.Common.Primitive;
//using DCRF.Common.Interface;

//namespace DCRF.Common.Kernel.Helper
//{
//    [Serializable]
//    [XmlRoot("Repository")]
//    /// <summary>
//    /// Block manager for SimpleBroker which manages blocks in a specific folder. Adding block to this repository means
//    /// copying the assembly file and side files to a folder named A\B\C in rep folder where A is product name, B is identifier
//    /// and C is version. Blocks metadata are stored in xml file.
//    /// </summary>
//    public class Repository
//    {
//        public Repository()
//        {
//            folder = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location),"default");
//        }

//        private string folder = null;

//        /// <summary>
//        /// The folder in which repository files are located
//        /// </summary>
//        [XmlIgnore]
//        public string Folder
//        {
//            get
//            {
//                return folder;
//            }
//            set
//            {
//                folder = value;
//            }
//        }

//        #region Block management
//        /// <summary>
//        /// copies assembly, side files and references of a Block to a
//        /// folder in the repository 
//        /// </summary>
//        /// <param name="cd"></param>
//        /// <param name="folder"></param>
//        /// <param name="cmp"></param>
//        private void CopyBlockFilesToRepository(BlockDescriptor cd, string folder, IBlock cmp)
//        {
//            //create the new folder for the Block and copy the assembly to that location
//            string newFolder = cd.Folder;
//            Directory.CreateDirectory(newFolder);

//            File.Copy(Path.Combine(folder, cd.MainAssembly), Path.Combine(newFolder, cd.MainAssembly), true);

//            //copy sid files to target folder
//            foreach (string sideFile in cd.SideFiles)
//            {
//                File.Copy(Path.Combine(folder, sideFile), Path.Combine(newFolder, sideFile), true);
//            }

//            foreach (AssemblyName reference in cmp.GetType().Assembly.GetReferencedAssemblies())
//            {
//                string name = reference.Name;

//                //ignore known references as they are available to blocks everytime
//                if (name.StartsWith("System.") || name.StartsWith("DCRF.") || name == "mscorlib")
//                {
//                    continue;
//                }

//                //copy referenced assemblies
//                string dllName = name + ".dll";

//                //copy this file
//                File.Copy(Path.Combine(folder, dllName), Path.Combine(newFolder, dllName), true);
//            }
//        }

//        /// <summary>
//        /// finds exact or compatible match (same major and minor version with highest build and revision number) 
//        /// with this version - null if nothing is found
//        /// </summary>
//        /// <param name="ID"></param>
//        /// <param name="version"></param>
//        /// <returns></returns>
//        public BlockDescriptor FindBlock(CID handle)
//        {
//            //first look for exact match
//            BlockDescriptor result = Array.Find<BlockDescriptor>(blocks,
//                delegate(BlockDescriptor cd)
//                {
//                    if ( cd.ID == handle )
//                    {
//                        return true;
//                    }
//                    return false;
//                }
//            );

//            if (result == null)
//            {
//                BlockDescriptor[] items = Array.FindAll<BlockDescriptor>(blocks,
//                    delegate(BlockDescriptor cd)
//                    {
//                        if ( cd.ID.IsCompatible(handle) )
//                        {
//                            return true;
//                        }
//                        return false;
//                    }
//                );

//                if (items.Length > 0)
//                {
//                    //now find maximum version between compatible versions
//                    result = items[0];

//                    for (int i = 1; i < items.Length; i++)
//                    {
//                        if (items[i].ID.BlockVersion > result.ID.BlockVersion)
//                        {
//                            result = items[i];
//                        }
//                    }
//                }
//            }

//            return result;
//        }

//        /// <summary>
//        /// Update block data (re-copy files)
//        /// </summary>
//        /// <param name="cd">Block to be updated</param>
//        public void UpdateBlock(BlockDescriptor cd)
//        {
//            string sourcePath = cd.OriginalFolder;
//            string targetPath = cd.Folder;

//            foreach (string fileName in Directory.GetFiles(targetPath))
//            {
//                string realFileName = Path.GetFileName(fileName);
//                string sourceFile = Path.Combine(sourcePath, realFileName);
//                string targetFile = Path.Combine(targetPath, realFileName);

//                if (File.Exists(sourceFile))
//                {
//                    if (File.Exists(targetFile))
//                    {
//                        string basePath = Path.GetDirectoryName(this.GetType().Assembly.Location);
//                        System.Diagnostics.Process p = System.Diagnostics.Process.Start(Path.Combine(basePath, "unlocker.exe"), targetFile + " /S /D");

//                        p.WaitForExit();
//                    }

//                    File.Copy(sourceFile, targetFile, true);
//                }
//            }
//        }

//        /// <summary>
//        /// Add a block to repository
//        /// </summary>
//        /// <param name="Block">Block info</param>
//        /// <param name="originalFolder">Original folder from which block files are to be read</param>
//        public void AddBlock(BlockDescriptor Block, string originalFolder)
//        {
//            IBlock cmp = new Loader().LoadBlock(Block.MainAssembly, Block.MainClass, originalFolder, null);

//            Block.Repository = this;
//            Block.OriginalFolder = originalFolder;
//            Block.InitFrom(cmp);

//            BlockDescriptor temp = FindBlock(cmp.BlockInfo.BlockID);
//            if (temp != null)
//            {
//                if (temp.ID.BlockVersion == Block.ID.BlockVersion)
//                {
//                    throw new Exception("Cannot add duplicate Blocks to repository.");
//                }
//            }
            
//            Array.Resize<BlockDescriptor>(ref blocks, blocks.Length + 1);
//            blocks[blocks.Length - 1] = Block;

//            CopyBlockFilesToRepository(Block, originalFolder, cmp);

//            Save();
//        }
//        /// <summary>
//        /// Delete the block specified by input argument from repository (metadata+physical files)
//        /// </summary>
//        /// <param name="Block">Block to be deleted</param>
//        public void DeleteBlock(BlockDescriptor Block)
//        {
//            string folder = Block.Folder;

//            //this line throws exception - file is locked
//            Directory.Delete(folder, true);

//            //delete descriptor from list of Blocks of this repository
//            int idx = Array.IndexOf<BlockDescriptor>(blocks, Block);

//            if (idx != -1)
//            {
//                for (int i = idx; i < blocks.Length; i++)
//                {
//                    blocks[i] = blocks[i + 1];
//                }

//                Array.Resize<BlockDescriptor>(ref blocks, blocks.Length - 1);
//            }

//            Save();
//        }
//        #endregion 

//        #region XML view of repository
//        private BlockDescriptor[] blocks = null;
        
//        /// <summary>
//        /// A list of BlockDescriptors for blocks in this repository
//        /// </summary>
//        public BlockDescriptor[] Blocks
//        {
//            get
//            {
//                if (blocks == null)
//                {
//                    Load();
//                }

//                return blocks;
//            }
//            set
//            {
//                blocks = value;

//                foreach (BlockDescriptor cd in blocks)
//                {
//                    cd.Repository = this;
//                }
//            }
//        }

//        #endregion

//        #region Repository Management

//        /// <summary>
//        /// Save repository metadata in dcrf.xml
//        /// </summary>
//        public void Save()
//        {
//            StreamWriter sw = new StreamWriter(Path.Combine(Folder, Const.RepositoryConfigFilename));
//            XmlSerializer xml = new XmlSerializer(typeof(Repository));

//            xml.Serialize(sw, this);

//            sw.Close();

//        }

//        /// <summary>
//        /// Load repository metadata from a xml file (dcrf.xml)
//        /// </summary>
//        public void Load()
//        {
//            StreamReader sr = new StreamReader(Path.Combine(Folder, Const.RepositoryConfigFilename));
//            XmlSerializer xml = new XmlSerializer(typeof(Repository));

//            Repository result = xml.Deserialize(sr) as Repository;
//            sr.Close();

//            blocks = result.blocks;

//            //set the Blocks' repository to this object
//            foreach (BlockDescriptor cd in blocks)
//            {
//                cd.Repository = this;
//            }
//        }

//        #endregion
//    }
//}
